﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using OT.Data;
using OT.Areas.Admin.Models;
using PagedList;
using System.Data.SqlClient;
namespace OT.Areas.Admin.Controllers
{
    public class TestController : Controller
    {
        #region Declaration
        readonly OTEntitiesme OTDb = new OTEntitiesme();
        int LanguageID = Utilities.GetLanguageID();
        #endregion

        #region ExtraCall
        [AcceptVerbs(HttpVerbs.Get)]
        public JsonResult IsQuestionForTest(int dt, int testid)
        {
            int cnt = 0;
            cnt = OTDb.TestQuestions.Where(p => p.TestID == testid && p.QuestionID == dt).Count();
            return Json(cnt, JsonRequestBehavior.AllowGet);
        }
        private IList<Subject> GetSub(int CategoryID)
        {
            return OTDb.Subjects.Where(m => m.CategoryID == CategoryID && m.Status==true).ToList();
        }
        [AcceptVerbs(HttpVerbs.Get)]
        public JsonResult LoadSubject(string CategoryID)
        {
            var stateList = this.GetSub(Convert.ToInt32(CategoryID));
            var stateData = stateList.Select(m => new SelectListItem()
            {
                Text = m.SubjectName,
                Value = m.SubjectID.ToString(),
            });
            return Json(stateData, JsonRequestBehavior.AllowGet);
        }

        public ActionResult ShowTestAttemptList(int TestID)
        {
            try
            {
                var Attempts = (List<TestAttemptDetail>)null;
                try
                {
                    Attempts = (from c in OTDb.AttemptMsts
                                where c.TestID.Value.Equals(TestID)
                                join top in OTDb.Users
                                on c.UserID equals top.UserID
                                join tst in OTDb.Tests
                                on c.TestID equals tst.TestID
                                select new TestAttemptDetail
                                {
                                    TestName = tst.TestName,
                                    StudentName = top.FirstName,
                                    IsFinish = (bool)c.IsFinish,
                                    Score = (float)c.Score,
                                    DateofExam = (DateTime)c.CreatedDate

                                }).ToList();
                }
                catch (Exception ex)
                {
                    Utilities.InsertErrorLog(ex);
                }
                return View(Attempts.ToPagedList(1, 300));
            }
            catch (Exception e)
            {
            }
            return View();

        }
        #endregion

        #region Index
        public ActionResult Index()
        {
            return View();
        }
        [HttpPost]
        public JsonResult Index(int pageNumber, int pageSize, string searchString, int pgindex)
        {
            List<Tests> test = (from c in OTDb.Tests
                                 join ttyp in OTDb.TestTypes
                                on c.TestTypeID equals ttyp.TestTypeID into output
                                 join top in OTDb.Topics
                                  on c.TopicID equals top.TopicID
                                 join usr in OTDb.Users
                                 on c.UserID equals usr.UserID
                                 join sub in OTDb.Subjects
                                on c.SubjectID equals sub.SubjectID
                                 from j in output.DefaultIfEmpty()
                                 select new Tests
                                 {
                                     TestID = c.TestID,
                                     TestName = c.TestName,
                                     Description = c.Description,
                                     TotalQuestion = (int)c.TotalQuestion,
                                     Duration = (int)c.Duration,
                                     PassingScore = (byte)c.PassingScore,
                                     PositiveMark = (byte)c.PositiveMark,
                                     NegativeMark = (byte)c.NegativeMark,
                                     TopicName = top.TopicName,
                                     UserName = usr.FirstName,
                                     Subject = sub.SubjectName,
                                      noofatmpt = OTDb.AttemptMsts.Where(a => a.TestID.Value.Equals(c.TestID)).Count<AttemptMst>(),
                                     TestType1 = j.TestType1,
                                     CreatedDate = (c.CreatedDate.HasValue) ? c.CreatedDate.Value : DateTime.MinValue,
                                     UpdatedDate = (c.UpdatedDate.HasValue) ? c.UpdatedDate.Value : DateTime.MinValue,
                                     Status = (bool)c.Status}
                                                        ).OrderBy(o => o.TestName).ToList<Tests>(); ;


            if (!string.IsNullOrEmpty(searchString))
                test = test.Where(r => r.TestName.ToLower().Contains(searchString.ToLower())).ToList();
            int recount = test.Count;
            test = test.Skip<Tests>(pgindex * (pageNumber - 1))
                .Take<Tests>(pgindex).ToList<Tests>();
            return Json(new
            {
                PageNumber = pageNumber,
                PageSize = pageSize,
                PgIndex = pgindex,
                Data = test,
                RecordCount = recount
            });
        }
        #endregion

        #region Create
        public ActionResult Create()
        {
           Tests Test = null;
           try
           {
               Test = new Tests();
               var tt = OTDb.TestTypes.ToList();
               Test.TestTypes = tt;
               var cat = OTDb.Categories.Where(c=>c.Status==true).ToList();
               Test.cat = cat;
               var sr = OTDb.Users.Where(c=>c.Status==true).ToList();
               Test.Users = sr;
               var top = OTDb.Topics.Where(t=>t.Status==true).ToList();
               Test.Topics = top;
               var Sub = OTDb.Subjects.Where(s=>s.Status==true).ToList();
               Test.Subjects = Sub;
           }
           catch (Exception ex)
           {
               Utilities.InsertErrorLog(ex);
           }
            return PartialView(Test);
        }
        [HttpPost]
        public string Create(string TestName, int TestTypeID, int CategoryID, int SubjectID, int TopicID, string Description, int TotalQuestion, int Duration, byte PassingScore, byte PositiveMark, byte NegativeMark, bool Status, string QuestionIDs, string StudentIDs)
        {
            string result = "";
            Test Test = null;
            TestQuestion TestQuestion = null;
            TestUser user = null;
            try
            {
                if (ModelState.IsValid)
                {
                    int UserID = 0;
                        if (Request.Cookies["AdminID"] != null)
                        {
                            UserID = Convert.ToInt16(Request.Cookies["AdminID"].Value);
                        }
                        else
                        {
                            TempData["notice"] = "Time Out ,Please Login";
                            Response.Redirect("~/Home");
                        }
                    Test = new Test();
                    Test.TestName = TestName;
                    Test.Description = Description;
                    Test.TotalQuestion = TotalQuestion;
                    Test.Duration = Duration;
                    Test.PassingScore = PassingScore;
                    Test.PositiveMark = PositiveMark;
                    Test.NegativeMark = NegativeMark;
                    Test.Status = Status;
                    if (TestTypeID != 0)
                        Test.TestTypeID = TestTypeID;
                    if (SubjectID != 0)
                        Test.SubjectID = SubjectID;
                    if (TopicID != 0)
                        Test.TopicID = TopicID;
                    Test.CategoryID = CategoryID;
                    Test.SubjectID = SubjectID;
                    Test.TopicID = TopicID;
                    Test.UserID = UserID;
                    Test.CreatedDate = DateTime.Now;
                    Test.UpdatedDate = DateTime.Now;
                    Test.LanguageID = LanguageID;
                    OTDb.Tests.Add(Test);
                    OTDb.SaveChanges();
                    if (string.IsNullOrEmpty(QuestionIDs))
                    {
                        var ql = OTDb.Questions.Where(r => r.SubjectID == SubjectID && r.TopicID == TopicID).ToList();
                        int cnt = 0;
                        foreach (Question drq in ql)
                        {
                            if (cnt < TotalQuestion)
                            {
                                TestQuestion = new TestQuestion();
                                TestQuestion.QuestionID = drq.QuestionID;
                                TestQuestion.TestID = Test.TestID;
                                OTDb.TestQuestions.Add(TestQuestion);
                                OTDb.SaveChanges();
                            }
                            cnt++;
                        }
                    }
                    else
                    {
                        string[] sep = { "," };
                        string[] IDs = QuestionIDs.Split(sep, StringSplitOptions.RemoveEmptyEntries);
                        List<int> ids = new List<int>();
                        foreach (var id in IDs)
                            ids.Add(Convert.ToInt32(id));
                        foreach (int QuestionID in ids)
                        {
                            TestQuestion = new TestQuestion();
                            TestQuestion.QuestionID = QuestionID;
                            TestQuestion.TestID = Test.TestID;
                            OTDb.TestQuestions.Add(TestQuestion);
                            OTDb.SaveChanges();
                        }
                    }
                    if (!string.IsNullOrEmpty(StudentIDs))
                    {

                        //values for StudentIDs is UnDefined

                        string[] sep = { "," };
                        string[] IDs = StudentIDs.Split(sep, StringSplitOptions.RemoveEmptyEntries);
                        List<int> ids = new List<int>();
                        foreach (var id in IDs)
                            ids.Add(Convert.ToInt32(id));
                        foreach (int StudentID in ids)
                        {
                            user = new TestUser();
                            user.UserID = StudentID;
                            user.TestID = Test.TestID;
                            OTDb.TestUsers.Add(user);
                            OTDb.SaveChanges();
                        }
                    }
                    else
                    {
                        var us = OTDb.Users.Where(p=>p.UserTypeID==3).ToList();
                        foreach (User drq in us)
                        {
                            user = new TestUser();
                            user.UserID = drq.UserID;
                            user.TestID = Test.TestID;
                            OTDb.TestUsers.Add(user);
                            OTDb.SaveChanges();
                        }
                    }
                    result = "Success";
                }
                else
                {
                    result = "NotValid";
                }
            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
            }
            return result;
        }
        #endregion

        #region Edit
        public ActionResult Edit(int TestID)
        {
            Tests Tests = null;
            try
            {
                var tst = OTDb.Tests.Where(r => r.TestID == TestID).SingleOrDefault();
                if (tst != null)
                {
                    Tests = new Tests();
                    Tests.TestID = tst.TestID;
                    HttpCookie myCookie = new HttpCookie("IDSettings");
                    myCookie["TestID"] = tst.TestID.ToString();
                    myCookie.Expires = DateTime.Now.AddDays(1d);
                    Response.Cookies.Add(myCookie);
                    Tests.TestName = tst.TestName;
                    Tests.Description = tst.Description;
                    Tests.totalStudent = OTDb.TestUsers.Where(c => c.TestID.Value.Equals(TestID)).Select(c => c.UserID).Count();
                    var Questionslist = OTDb.TestQuestions.Where(r => r.TestID.Value.Equals(tst.TestID)).ToList();
                    if (Questionslist != null)
                    {
                       
                        Tests.totalAvailQue = Questionslist.Count;
                    }
                    string res = GetAvailableQuestion((int)tst.SubjectID, (int)tst.TopicID);
                    Tests.totalAvailQue = Convert.ToInt16(res);
                    Tests.Status = (bool)tst.Status;
                    if (tst.TestTypeID != null)
                        Tests.TestTypeID = (int)tst.TestTypeID;
                    if (tst.SubjectID != null)
                        Tests.SubjectID = (int)tst.SubjectID;
                    if (tst.TopicID != null)
                        Tests.TopicID = (int)tst.TopicID;
                    Tests.TotalQuestion = Questionslist.Count;
                    Tests.Duration = (int)tst.Duration;
                    Tests.PassingScore = (byte)tst.PassingScore;
                    Tests.PositiveMark = (byte)tst.PositiveMark;
                    Tests.NegativeMark = (byte)tst.NegativeMark;
                    Tests.SubjectID = (int)tst.SubjectID;
                    Tests.TopicID = (int)tst.TopicID;
                    Tests.CategoryID = tst.CategoryID.Value;
                    var top = OTDb.Topics.Where(t => t.SubjectID.Value.Equals(tst.SubjectID.Value)).ToList();
                    Tests.Topics = top;
                    var sub = OTDb.Subjects.Where(s => s.CategoryID.Value.Equals(tst.CategoryID.Value)).ToList();
                    Tests.Subjects = sub;
                    var category = OTDb.TestTypes.ToList();
                    Tests.TestTypes = category;
                    var cat = OTDb.Categories.ToList();
                    Tests.cat = cat;
                }
            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
            }
            return PartialView(Tests);
        }

        [HttpPost]
        public string Edit(int TestID, string TestName, int TestTypeID, int CategoryID, int SubjectID, int TopicID, string Description, int TotalQuestion, int Duration, byte PassingScore, byte PositiveMark, byte NegativeMark, bool Status, string QuestionIDs, string StudentIDs)
        {
            string result = "";
            TestQuestion TestQuestion = null;
            TestUser user = null;
            try
            {
                if (ModelState.IsValid)
                {
                    var category = OTDb.Tests.Where(r => r.TestID == TestID).SingleOrDefault();
                    if (category != null)
                    {
                        category.TestName = TestName;
                        category.Description = Description;
                        category.Duration = Duration;
                        category.TotalQuestion = TotalQuestion;
                        category.PassingScore = PassingScore;
                        category.PositiveMark = PositiveMark;
                        category.NegativeMark = NegativeMark;
                        category.UpdatedDate = DateTime.Now;
                        category.Status = Status;
                        if (TestTypeID != 0)
                            category.TestTypeID = TestTypeID;
                        if (TopicID != 0)
                            category.TopicID = TopicID;
                        if (SubjectID != 0)
                            category.SubjectID = SubjectID;
                        if (string.IsNullOrEmpty(QuestionIDs))
                        {
                            var ql = OTDb.Questions.Where(r => r.SubjectID == SubjectID && r.TopicID == TopicID).ToList();
                            int cnt = 0;
                            foreach (Question drq in ql)
                            {
                                if (cnt < TotalQuestion)
                                {
                                    if (!IsTestQuestionExist(TestID, drq.QuestionID, CategoryID))
                                    {
                                        if (CategoryID != 0)
                                            category.CategoryID = CategoryID;
                                        TestQuestion = new TestQuestion();
                                        TestQuestion.QuestionID = drq.QuestionID;
                                        TestQuestion.TestID = TestID;
                                        OTDb.TestQuestions.Add(TestQuestion);
                                        OTDb.SaveChanges();
                                    }
                                }
                                cnt++;
                            }
                        }
                        else
                        {
                            string[] sep = { "," };
                            string[] IDs = QuestionIDs.Split(sep, StringSplitOptions.RemoveEmptyEntries);
                            List<int> ids = new List<int>();
                            foreach (var id in IDs)
                                ids.Add(Convert.ToInt32(id));
                            List<TestQuestion> test = OTDb.TestQuestions.Where(t => t.TestID.Value.Equals(TestID)).ToList();
                            foreach (TestQuestion tst in test)
                            {
                                OTDb.TestQuestions.Remove(tst);
                                OTDb.SaveChanges();
                            }
                            foreach (int QuestionID in ids)
                            {
                                if (CategoryID != 0)
                                    category.CategoryID = CategoryID;
                                TestQuestion = new TestQuestion();
                                TestQuestion.QuestionID = QuestionID;
                                TestQuestion.TestID = TestID;
                                OTDb.TestQuestions.Add(TestQuestion);
                                OTDb.SaveChanges();
                            }
                        }

                        if (!string.IsNullOrEmpty(StudentIDs))
                        {
                            string[] sep = { "," };
                            string[] IDs = StudentIDs.Split(sep, StringSplitOptions.RemoveEmptyEntries);
                            List<int> ids = new List<int>();
                            foreach (var id in IDs)
                                ids.Add(Convert.ToInt32(id));
                            List<TestUser> users = OTDb.TestUsers.Where(t => t.TestID.Value.Equals(TestID)).ToList();

                            if (users.Count != 0)
                            {
                                foreach (TestUser usr in users)
                                {
                                    OTDb.TestUsers.Remove(usr);
                                    OTDb.SaveChanges();
                                }
                            }
                            foreach (int StudentID in ids)
                            {
                                user = new TestUser();
                                user.UserID = StudentID;
                                user.TestID = TestID;
                                OTDb.TestUsers.Add(user);
                                OTDb.SaveChanges();
                            }
                        }
                        else
                        {
                            var us = OTDb.Users.Where(p=>p.UserTypeID==3).ToList();
                            foreach (User drq in us)
                            {
                                if (!IsTestUserExist(TestID, drq.UserID))
                                {
                                    user = new TestUser();
                                    user.UserID = drq.UserID;
                                    user.TestID = TestID;
                                    OTDb.TestUsers.Add(user);
                                    OTDb.SaveChanges();
                                }
                            }
                        }
                        result = "Success";
                    }
                }
                else
                {
                    result = "NotValid";

                }
            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
                result = "NotValid";
            }
            return result;
        }
        #endregion

        #region ISTestUserExist
        public bool IsTestUserExist(int TestID, int UserID)
        {
            bool response = false;
            try
            {
                var Questionslist = OTDb.TestUsers.Where(r => r.TestID.Value == TestID && r.UserID.Value == UserID).ToList();
                if (Questionslist.Count != 0)
                {
                    response = true;
                }
                List<TestUser> users = OTDb.TestUsers.Where(t => t.TestID.Value.Equals(TestID)).ToList();

                if (users.Count != 0)
                {
                    foreach (TestUser usr in users)
                    {
                        OTDb.TestUsers.Remove(usr);
                        OTDb.SaveChanges();
                    }
                }

            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
            }
            return response;
        }
        #endregion

        #region Delete
        public ActionResult Delete(int TestID)
        {
            Tests topc = null;
            try
            {
                var categry = OTDb.Tests.Where(r => r.TestID == TestID).SingleOrDefault();
                if (categry != null)
                {
                    topc = new Tests();
                    topc.TestName = categry.TestName;
                    topc.TestID = categry.TestID;
                    topc.SubjectID = categry.SubjectID;
                    topc.Description = categry.Description;
                    topc.UserID = categry.UserID;
                    topc.LanguageID = LanguageID;
                }
            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
            }
            return PartialView(topc);
        }

        [HttpPost]
        public string Delete(int TestID, string IsDelete)
        {
            string result = "";
            try
            {
                var cat = OTDb.Tests.Where(r => r.TestID == TestID).SingleOrDefault();
                if (cat != null)
                {
                    OTDb.Tests.Remove(cat);
                    OTDb.SaveChanges();
                    result = "Success";
                }
            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
            }
            return result;
        }
#endregion

        #region JsonCall
        [HttpGet]
        public ActionResult CustomizeQuestion(int SubjectId, int TopicID)
        {
            return View();
        }
        private IList<Topic> GetTopic(int SubjectID)
        {
            return OTDb.Topics.Where(c => c.SubjectID == SubjectID && c.Status==true).ToList();
        }
        [AcceptVerbs(HttpVerbs.Get)]
        public JsonResult LoadTopic(string SubjectID)
        {
            var CityList = this.GetTopic(Convert.ToInt32(SubjectID));
            var CityData = CityList.Select(c => new SelectListItem()
            {
                Text = c.TopicName,
                Value = c.TopicID.ToString(),
            });
            return Json(CityData, JsonRequestBehavior.AllowGet);
        }
        public int avail(int SubjectID, int TopicID)
        {
            var query1 = (from c in OTDb.Questions
                          where c.SubjectID == SubjectID && c.TopicID == TopicID && c.Status == true
                          select c).Count();
            return query1;
        }
        [AcceptVerbs(HttpVerbs.Get)]
        public JsonResult AvailQue(int SubjectID, int TopicID)
        {
            var query1 = (from c in OTDb.Questions
                          where c.SubjectID == SubjectID && c.TopicID==TopicID && c.Status==true
                          select c).Count();
                       return Json(query1, JsonRequestBehavior.AllowGet);
        }
        public bool IsTestQuestionExist(int TestID, int QuestionID, int CategoryID)
        {
            bool response = false;
            try
            {
                var Questionslist = OTDb.TestQuestions.Where(r => r.TestID.Value == TestID && r.QuestionID.Value == QuestionID).ToList();
                if (Questionslist.Count != 0)
                {
                    response = true;
                }
                List<TestQuestion> TestQuestion = OTDb.TestQuestions.Where(r => r.TestID.Value == TestID).ToList();
                foreach (TestQuestion tst in TestQuestion)
                {
                    if (!tst.Test.CategoryID.Value.Equals(CategoryID))
                    {
                        OTDb.TestQuestions.Remove(tst);
                        OTDb.SaveChanges();
                    }
                }
            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
            }
            return response;
        }
        public string GetAvailableQuestion(int SubjectID, int TopicID)
        {
            string response = string.Empty;
            try
            {
                var Questionslist = OTDb.Questions.Where(r => r.SubjectID.Value == SubjectID && r.TopicID.Value == TopicID && r.Status == true).ToList();
                if (Questionslist != null)
                {
                    response = Questionslist.Count.ToString();
                }
            }
            catch (Exception ex)
            {
                Utilities.InsertErrorLog(ex);
            }
            return response;
        }
        public static List<SelctedQuestionList_Result> data1obj;
        public ActionResult ShowAllQuestion(int subjectId, int topicid, int testid)
        {
            data1obj = OTDb.SelctedQuestionList(subjectId, topicid, testid).ToList<SelctedQuestionList_Result>();
            return PartialView(data1obj.ToPagedList(1, 1000));
        }

        public static List<sp_CustomeQuestionList_Result> custom;
        public ActionResult ShowAllQuestionCreate(int subjectId, int topicid)
        {
            custom = OTDb.sp_CustomeQuestionList(subjectId, topicid).ToList<sp_CustomeQuestionList_Result>();
            return PartialView(custom.ToPagedList(1, 1000));
            //var Questionslist = (List<Question>)null;
            //Questionslist = (from c in OTDb.Questions
            //                 where c.SubjectID.Value.Equals(subjectId) && c.TopicID.Value.Equals(topicid) && c.Status == true
            //                 select c).ToList();

            //return PartialView(Questionslist.ToPagedList(1, 1000));
        }
        public ActionResult GetAllStudent()
        {
            var StudentList = (List<StudentListAdmin>)null;
            StudentList = (from c in OTDb.Users
                           where c.UserTypeID == 3 && c.Status==true
                           select new StudentListAdmin
                           {
                               UserID = c.UserID,
                               Name = c.FirstName + "-" + c.LastName,

                               RegistrationDate = c.CreatedDate == null ? DateTime.Today : (DateTime)c.CreatedDate
                           }
                           ).ToList();

            return PartialView(StudentList.ToPagedList(1, 100000));
        }

        public JsonResult GetTestUsers(int TestID)
        {
            List<TestUserAdmin> StudentList = (from c in OTDb.TestUsers
                                           where c.TestID.Value.Equals(TestID)
                                               select new TestUserAdmin { UserID = c.UserID.Value, TestID = c.TestID.Value, TestUserID = c.TestUserID }).ToList();
            return Json(new
            {
                Data = StudentList,
            });

        }
        #endregion
    }
}
